'use strict';

const co      = require('co');
const redis   = require('redis');
const Promise = require('bluebird');

Promise.promisifyAll(redis);

var client = redis.createClient();

var isLogin = function *(ctx) {
    var uid        = ctx.cookies.get('uid'),
        uname      = ctx.cookies.get('uname'),
        authsecert = ctx.cookies.get('authsecert');

    if (!uid || !uname || !authsecert) return false;

    var ret = co(function *() {
        return yield client.getAsync(`user:uid:${uid}:authsecert:`);
    }).then(authSecertOnServer => {
        if (authsecert != authSecertOnServer) return false;
        return {
            'uid'  : uid,
            'uname': uname
        };
    });

    return yield ret;
};

var randSecert = () => Math.random().toString(36).substr(2, 16);

module.exports = function (router) {
    router
        .get('/', function *(next) {
            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (logined) return ctx.redirect('/home');
            // this.render和return this.render都不行,必须使用yield
            yield this.render('index');
        })
        .post('/reg', function *(next) {

            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (logined) return ctx.redirect('/home');

            var body      = ctx.request.body;
            var username  = body.username,
                password  = body.password,
                password2 = body.password2;

            if (!username || !password || !password2) return ctx.body = '注册信息不完善';

            if (password !== password2) return ctx.body = '两次密码不一致';

            var key      = `user:uname:${username}:uid`;
            var isExists = yield client.existsAsync(key);
            if (isExists) {
                ctx.body = '用户被占用';
            } else {
                let uidKey = 'global:uid';
                let uid    = yield client.incrAsync(uidKey);
                yield co(function *() {
                    yield [
                        client.setAsync(`user:uid:${uid}:uname`, username),
                        client.setAsync(`user:uid:${uid}:password`, password),
                        client.setAsync(`user:uname:${username}:uid`, uid)
                    ];
                });
                ctx.body = '注册成功';

                // 通过链表维护最新的50个uid
                yield client.lpushAsync('newregusers', uid);
                client.ltrimAsync('newregusers', 0, 49);
            }
        })
        .post('/login', function *(next) {
            var body     = this.request.body;
            var username = body.username,
                password = body.password;

            var uid = yield client.getAsync(`user:uname:${username}:uid`);

            if (!uid) return this.body = '用户名不存在';

            var realPass = yield client.getAsync(`user:uid:${uid}:password`);

            if (realPass != password) return this.body = '密码错误';

            var authSecert = randSecert();
            yield client.setAsync(`user:uid:${uid}:authsecert:`, authSecert);

            this.cookies.set('uname', username);
            this.cookies.set('uid', uid);
            this.cookies.set('authsecert', authSecert);
            this.redirect('/home');
        })
        .get('/logout', function *(next) {
            var uid = this.cookies.get('uid');
            this.cookies.set('uname', '', {expires: new Date()});
            this.cookies.set('uid', '', {expires: new Date()});
            this.cookies.set('authsecert', '', {expires: new Date()});

            yield client.delAsync(`user:uid:${uid}:authsecert:`);
            this.redirect('/');
        })
        .post('/post', function *(next) {
            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (!logined) return ctx.redirect('/');

            var content = ctx.request.body.status;
            if (!content) return ctx.body = '内容不能为空';

            var postid = yield client.incrAsync('global:postid');

            // yield co(function *() {
            //     yield [
            //         client.setAsync(`post:postid:${postid}:uid`, ctx.cookies.uid),
            //         client.setAsync(`post:postid:${postid}:time`, Date.now()),
            //         client.setAsync(`post:postid:${postid}:content`, content)
            //     ];
            // });

            // 微博改用hash存储结构
            yield client.hmsetAsync(`post:postid:${postid}`, {
                'uid'    : logined['uid'],
                'uname'  : logined['uname'],
                'time'   : Date.now(),
                'content': content
            });

            // 把微博推送给自己的粉丝
            var fans = yield client.smembersAsync(`follower:${logined['uid']}`);
            fans.forEach(fansid => {
                client.lpushAsync(`receivepost:${fansid}`, postid);
            });
            ctx.redirect('/home');
        })
        .get('/home', function *(next) {
            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (!logined) return ctx.redirect('/');

            var uid = logined['uid'];
            yield client.ltrimAsync(`receivepost:${uid}`, 0, 49);
            var postids  = yield client.sortAsync(`receivepost:${uid}`, 'desc');
            var postList = yield postids.map(postid => client.hgetallAsync(`post:postid:${postid}`));
            // console.log(postList);

            var followersCount = yield client.scardAsync(`following:${uid}`),
                starCount      = yield client.scardAsync(`follower:${uid}`);

            // console.log(followersCount,starCount);
            yield this.render('home', {
                'uname'         : this.cookies.get('uname'),
                'postList'      : postList,
                'followersCount': followersCount,
                'starCount'     : starCount
            });
        })
        .get('/timeline', function *(next) {
            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (!logined) return ctx.redirect('/');

            // redis 中sort命令的用法,参见https://github.com/NodeRedis/node_redis/issues/103
            var newRegUsers = yield client.sortAsync('newregusers', 'desc', 'get', 'user:uid:*:uname');
            console.log('newRegUsers',newRegUsers);
            yield this.render('timeline', {
                unames: newRegUsers
            });
        })
        .get('/profile/:uname', function *(next) {
            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (!logined) return ctx.redirect('/');

            // console.log('uname', this.params.uname);
            var myUid = yield client.getAsync(`user:uname:${this.params.uname}:uid`);
            if (!myUid) return this.body = '非法用户';

            var isFollow  = yield client.sismemberAsync(`following:${this.cookies.get('uid')}`, myUid);
            var isFstatus = isFollow ? '0' : '1';
            var isFword   = isFollow ? '取消关注' : '关注ta';

            yield this.render('profile', {
                'myUid'    : myUid,
                'isFstatus': isFstatus,
                'isFword'  : isFword
            });
        })
        .get('/follow', function *(next) {
            var ctx     = this;
            var logined = yield isLogin(ctx);
            if (!logined) return ctx.redirect('/');

            var uid = ctx.query.uid,
                f   = ctx.query.f;

            // 关注
            if (f == 1) {
                yield co(function *() {
                    yield [
                        client.saddAsync(`following:${ctx.cookies.get('uid')}`, uid),
                        client.saddAsync(`follower:${uid}`, `${ctx.cookies.get('uid')}`)
                    ];
                });
            } else if (f == 0) {
                // 取消关注
                yield co(function *() {
                    yield [
                        client.sremAsync(`following:${ctx.cookies.get('uid')}`, uid),
                        client.sremAsync(`follower:${uid}`, `${ctx.cookies.get('uid')}`)
                    ];
                });
            }

            var uname = yield client.getAsync(`user:uid:${uid}:uname`);
            ctx.redirect(`/profile/${uname}`);
        });
};
